//var 弊端1
var tmp = new Date();

function f() {
	console.log(tmp);
	if (false) {
		var tmp = 'hello world'; //在内部变量提升 覆盖了外面的 
	}
}

f(); // undefined



//var弊端2
var s = 'hello';
for (var i = 0; i < s.length; i++) {
	console.log(s[i]);
}
console.log(i); // 5  上面代码中，变量i只用来控制循环，但是循环结束后，它并没有消失，泄露成了全局变量。


function f1() {
	let n = 5; //两个n相互隔离 换成var的话结果就为10
	if (true) {
		let n = 10;
	}
	console.log(n); // 5
}
f1()


//ES6 允许块级作用域的任意嵌套。

{
	{
		{
			{
				{
					let insane = 'Hello World'
				}
				console.log(insane); // 报错
			}
		}
	}
};

//内层作用域可以定义外层作用域的同名变量。

{
	{
		{
			{
				let insane = 'Hello World' {
					let insane = 'Hello World'
				}
			}
		}
	}
};


//块级作用域的出现，实际上使得获得广泛应用的匿名立即执行函数表达式（匿名 IIFE）不再必要了。
// IIFE 写法
(function() {
	var tmp = ...;
	...
}());
// 块级作用域写法
{
	let tmp = ...;
	...
}


/*

 最好不要在块级作用域里声明函数,即使有时候不会报错.
 
 如果确实需要，也应该写成函数表达式，而不是函数声明语句。
 
 函数的声明和let类似
 
let f = function () { √
    return a;
  };
  
  function f() {×
      return a;
    }
	
*/
